import time
import threading
import sys
from cushy_serial import CushySerial
from BrainLinkParser import BrainLinkParser
import pygame
import numpy as np

# ============== 配置 ==============
COM_PORT = "COM6"          # 已改为 COM5

# 全局退出标志
running = threading.Event()
running.set()

# 初始化音频（双声道，解决之前的声音错误）
pygame.mixer.init(frequency=44100, size=-16, channels=2, buffer=512)

def play_note(freq=523, duration=0.25, volume=0.8):
    """生成钢琴音"""
    sample_rate = 44100
    t = np.linspace(0, duration, int(sample_rate * duration), False)
    tone = np.sin(2 * np.pi * freq * t)
    envelope = np.exp(-3.5 * t)
    audio = (tone * envelope * volume * 32767).astype(np.int16)
    stereo_audio = np.column_stack((audio, audio))   # 双声道
    sound = pygame.sndarray.make_sound(stereo_audio)
    sound.play()

# ============== EEG 回调 ==============
def on_eeg(data):
    attention = getattr(data, 'attention', 0)
    meditation = getattr(data, 'meditation', 0)
    blink = getattr(data, 'blinkStrength', getattr(data, 'blink', 0))

    print(f"专注度: {attention:3d} | 放松度: {meditation:3d} | 眨眼: {blink:3d}")
    sys.stdout.flush()   # 让打印立即显示

    if attention > 50:
        freq = 523 + (attention - 50) * 10
        play_note(freq, 0.20, 0.85)
    elif meditation > 45:
        freq = 330 + (meditation - 45) * 5
        play_note(freq, 0.45, 0.75)
    if blink > 60:
        play_note(784, 0.15, 0.95)

def on_extend_eeg(data): pass
def on_gyro(x, y, z): pass
def on_rr(rr1, rr2, rr3): pass
def on_raw(raw): pass

parser = BrainLinkParser(on_eeg, on_extend_eeg, on_gyro, on_rr, on_raw)

# ============== 串口线程 ==============
def start_brainlink():
    serial = None
    try:
        serial = CushySerial(COM_PORT, 115200)
        print(f"✅ 串口 {COM_PORT} 打开成功！")

        @serial.on_message()
        def handle_message(msg: bytes):
            if msg and running.is_set():
                parser.parse(msg)

        print("🎹 Brainlink Pro 连接成功！用意念弹钢琴吧！")
        print("   专注度高 → 高音活泼    放松度高 → 低音柔和    眨眼 → 强音\n")

        # 测试音
        print("播放测试音（3个音）...")
        time.sleep(0.3)
        play_note(523, 0.5, 0.9)
        time.sleep(0.6)
        play_note(659, 0.5, 0.9)
        time.sleep(0.6)
        play_note(784, 0.5, 0.95)
        print("测试音结束。\n")

        while running.is_set():
            time.sleep(0.1)

    except Exception as e:
        print(f"❌ 错误: {e}")
    finally:
        if serial:
            try:
                serial.close()
            except:
                pass

# ============== 干净退出 ==============
def graceful_shutdown():
    print("\n正在退出程序，请稍等...")
    running.clear()
    time.sleep(0.8)      # 给串口线程更多时间停止
    pygame.mixer.quit()
    print("🎹 程序已安全退出")
    sys.stdout.flush()
    # 强制退出
    import os
    os._exit(0)

# ============== 主程序 ==============
if __name__ == "__main__":
    thread = threading.Thread(target=start_brainlink, daemon=True)
    thread.start()

    print("程序运行中... 按 Ctrl + C 退出")

    try:
        while running.is_set():
            time.sleep(0.3)
    except KeyboardInterrupt:
        graceful_shutdown()
    except Exception:
        graceful_shutdown()